#include "ChartController.h"

ChartController::ChartController(Chart *chart)
    : QObject(chart)
    , _chart(chart)
{
    _handlers["init"] = [this](const QVector<QString> &data) -> bool
    {
        if (data.isEmpty())
        {
            return false;
        }

        _chart->initFlexible(data[0]);
        return true;
    };
    _handlers["initFixed"] = [this](const QVector<QString> &data) -> bool
    {
        if (data.size() < 5)
        {
            return false;
        }

        {
            bool ok = true;
            constexpr auto to_double = [](const QString &s, bool &ok) -> double
            {
                auto tmp_ok = false;
                auto d = s.toDouble(&tmp_ok);
                ok = ok && tmp_ok;
                return d;
            };

            Chart::Ranges ranges(
                to_double(data[1], ok), to_double(data[2], ok)
                , to_double(data[3], ok), to_double(data[4], ok)
            );

            if (!ok)
            {
                return false;
            }

            if (data[0] == "set_view")
            {
                _chart->setView(ranges);
            }
            else
            {
                _chart->initFixed(data[0], ranges);
            }
        }

        return true;
    };
    _handlers["addSeries"] = [this](const QVector<QString> &data) -> bool
    {
        if (data.size() == 0 || data.size() % 2 != 0)
            return false;

        for (auto it = data.constBegin(); it != data.constEnd(); it += 2)
        {
            _chart->replaceSeries(*it, Chart::Style((it + 1)->toInt()));
        }
        return true;
    };
    _handlers["addPoint"] = [this](const QVector<QString> &data) -> bool
    {
        if (data.size() == 0 || data.size() % 3 != 0)
            return false;

        QHash<QString, QVector<QPointF>> series;
        for (auto it = data.cbegin(); it != data.cend(); it += 3)
        {
            series[*it].append({(it + 1)->toDouble(), (it + 2)->toDouble()});
        }
        for (auto it = series.cbegin(); it != series.cend(); ++it)
        {
            _chart->addPoints(it.key(), it.value());
        }
        return true;
    };
    _handlers["show"] = [this](const QVector<QString> &data) -> bool
    {
        if (!data.empty())
        {
            return false;
        }
        return true;
    };
}

void ChartController::started() 
{}

void ChartController::paused() 
{}

void ChartController::stoped()
{}

bool ChartController::acceptData(const QString &func, QVector<QString> &data)
{
    auto it = _handlers.find(func);
    
    if (it == _handlers.end())
    {
        return false;
    }

    return (*it)(data);
}
